﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Web.Razor;
using System.IO;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using Microsoft.CSharp;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Text.RegularExpressions;


namespace RazorLab
{
    public class TestRazorEnginHost : RazorEngineHost
    {
        public TestRazorEnginHost() : base(new CSharpRazorCodeLanguage())
        {
            
        }

        public override string DefaultBaseClass
        {
            get
            {
                return "PageBase";
            }
            set
            {
                base.DefaultBaseClass = value;
            }
        }

        public override string DefaultClassName
        {
            get
            {
                return "PageInherit";
            }
            set
            {
                base.DefaultClassName = value;
            }
        }

        public override void PostProcessGeneratedCode(System.CodeDom.CodeCompileUnit codeCompileUnit, System.CodeDom.CodeNamespace generatedNamespace, System.CodeDom.CodeTypeDeclaration generatedClass, System.CodeDom.CodeMemberMethod executeMethod)
        {
            base.PostProcessGeneratedCode(codeCompileUnit, generatedNamespace, generatedClass, executeMethod);
            generatedNamespace.Imports.Add(new CodeNamespaceImport("RazorLab"));
        }
 
    }

    public class PageBase
    {
        public PageBase()
        {
            HtmlCode = string.Empty;
        }
        public string HtmlCode { get; set; }
        public virtual void Execute() { }
        protected void WriteLiteral(string target)
        {
            HtmlCode += target;
        }

        protected void Write(object target)
        {
            HtmlCode += target.ToString();
        }

    }



    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {

            TestRazorEnginHost host = new TestRazorEnginHost();
            System.Web.Razor.RazorTemplateEngine rte = new System.Web.Razor.RazorTemplateEngine(host); 

            FileStream fs = new FileStream(@"C:\Test.cshtml",FileMode.Open);
            StreamReader sr = new StreamReader(fs);
            var codeDomWrap = rte.GenerateCode(sr);
            CSharpCodeProvider provider = new CSharpCodeProvider();

            CodeGeneratorOptions options = new CodeGeneratorOptions();
            options.BlankLinesBetweenMembers = false;
            options.IndentString = "\t";

            StringWriter sw = new StringWriter();
            string code = string.Empty;
            try
            {
                provider.GenerateCodeFromCompileUnit(codeDomWrap.GeneratedCode, sw, options);
                sw.Flush();
                code = sw.GetStringBuilder().ToString();
                Debug.WriteLine(code);
            }
            catch { }
            finally
            {
                sw.Close();
            }

            CompilerParameters c_options = new CompilerParameters();
            c_options.IncludeDebugInformation = false;
            c_options.GenerateExecutable = false;
            c_options.GenerateInMemory = true;
            c_options.ReferencedAssemblies.Add( "System.dll" );
            c_options.ReferencedAssemblies.Add(@"D:\Project\C#\MyMvc\RazorLab\bin\Debug\RazorLab.dll");
            CompilerResults results = provider.CompileAssemblyFromSource(c_options, code);
            provider.Dispose();
            Assembly generatedAssembly = null;
            if (results.Errors.Count == 0)
            {
                generatedAssembly = results.CompiledAssembly;
                //assert
                Type type = generatedAssembly.GetType(host.DefaultNamespace + "." + host.DefaultClassName);
                object instance = Activator.CreateInstance(type);
                object returnValue = type.InvokeMember("Execute", 
                    BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance, null, instance, null);
                Debug.WriteLine("\r\n");
                Debug.WriteLine(type.GetProperty("HtmlCode",BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty).GetValue(instance, null));
            }
            else
            {
                Debug.WriteLine("\r\n");
                foreach (CompilerError e in results.Errors)
                {
                    Debug.WriteLine(e.ErrorText);
                }
            }



        }        
    
        //[TestMethod]
        //public void TestMethod2()
        //{
        //    FileStream fs = new FileStream(@"C:\email (2).txt", FileMode.Open);
        //    StreamReader sr = new StreamReader(fs,Encoding.Default);
        //    string input = sr.ReadToEnd();
        //    Regex regex = new Regex("<[^>]*>|\r\n");
        //    string output = regex.Replace(input, string.Empty);
        //    output = output.Replace("&nbsp;", " ");
        //    output = output.Replace("&lt;", "<");
        //    output = output.Replace("&gt;", ">");
        //    output = output.Replace("&apos;", "'");
        //    output = output.Replace("&quot;", "\"");
        //    output = output.Replace("&amp;", "&");
        //    Debug.WriteLine(output);
        //}
    }
}
